#include "usart.h"

#if defined(BSP_USING_UART1)
static void usart1_msp_init(void)
{
#if defined(USART1_TX_A9_RX_A10)
    GPIO_InitType GPIO_InitStruct;
    /* enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA,ENABLE);
    /* connect port to USART1_Tx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_9;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;    
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    /* connect port to USART1_Rx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
#elif defined(USART1_TX_B6_RX_B7)
    GPIO_InitType GPIO_InitStruct;
    /* enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO | RCC_APB2PERIPH_GPIOB,ENABLE);
    /* USART1 remap enable */
    GPIO_PinsRemapConfig(GPIO_Remap_USART1,ENABLE);    
    /* connect port to USART1_Tx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_6;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;    
    GPIO_Init(GPIOB,&GPIO_InitStruct);
    /* connect port to USART1_Rx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_7;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStruct);
#endif
}
#endif /* BSP_USING_UART1 */

#if defined(BSP_USING_UART2)
static void usart2_msp_init(void)
{
#if defined(USART2_TX_A2_RX_A3)
    GPIO_InitType GPIO_InitStruct;
    /* enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA,ENABLE);
    /* connect port to USART1_Tx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_2;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;    
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    /* connect port to USART1_Rx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_3;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
#elif defined(USART2_TX_D5_RX_D6)
    GPIO_InitType GPIO_InitStruct;
    /* enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO | RCC_APB2PERIPH_GPIOD,ENABLE);
    /* USART1 remap enable */
    GPIO_PinsRemapConfig(GPIO_Remap_USART2,ENABLE);    
    /* connect port to USART1_Tx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_5;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;    
    GPIO_Init(GPIOD,&GPIO_InitStruct);
    /* connect port to USART1_Rx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_6;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(GPIOD,&GPIO_InitStruct);
#endif
}
#endif /* BSP_USING_UART2 */


#if defined(BSP_USING_UART3)
static void usart3_msp_init(void)
{
#if defined(USART3_TX_B10_RX_B11)
    GPIO_InitType GPIO_InitStruct;
    /* enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA,ENABLE);
    /* connect port to USART1_Tx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;    
    GPIO_Init(GPIOB,&GPIO_InitStruct);
    /* connect port to USART1_Rx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_11;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStruct);
#elif defined(USART3_TX_C10_RX_C11)
    GPIO_InitType GPIO_InitStruct;
    /* enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO | RCC_APB2PERIPH_GPIOC,ENABLE);
    /* USART1 remap enable */
    GPIO_PinsRemapConfig(GPIO_PartialRemap_USART3,ENABLE);    
    /* connect port to USART1_Tx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;    
    GPIO_Init(GPIOC,&GPIO_InitStruct);
    /* connect port to USART1_Rx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_11;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(GPIOC,&GPIO_InitStruct);
#elif defined(USART3_TX_D8_RX_D9)    
    GPIO_InitType GPIO_InitStruct;
    /* enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO | RCC_APB2PERIPH_GPIOD,ENABLE);
    /* USART1 remap enable */
    GPIO_PinsRemapConfig(GPIO_FullRemap_USART3,ENABLE);    
    /* connect port to USART1_Tx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_8;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;    
    GPIO_Init(GPIOD,&GPIO_InitStruct);
    /* connect port to USART1_Rx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_9;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(GPIOD,&GPIO_InitStruct);
#endif
}
#endif /* BSP_USING_UART3 */


#if defined(BSP_USING_UART4)
static void uart4_msp_init(void)
{
#if defined(UART4_TX_C10_RX_C11)
    GPIO_InitType GPIO_InitStruct;
    /* enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOC,ENABLE);
    /* connect port to USART1_Tx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;    
    GPIO_Init(GPIOC,&GPIO_InitStruct);
    /* connect port to USART1_Rx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_11;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(GPIOC,&GPIO_InitStruct);
#endif
}
#endif /* BSP_USING_UART4 */


#if defined(BSP_USING_UART5)
static void uart5_msp_init(void)
{
#if defined(UART5_TX_C12_RX_D2)
    GPIO_InitType GPIO_InitStruct;
    /* enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOC | RCC_APB2PERIPH_GPIOD,ENABLE);
    /* connect port to USART1_Tx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_12;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;    
    GPIO_Init(GPIOC,&GPIO_InitStruct);
    /* connect port to USART1_Rx */
    GPIO_InitStruct.GPIO_Pins = GPIO_Pins_2;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
    GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(GPIOD,&GPIO_InitStruct);
#endif
}
#endif /* BSP_USING_UART5 */

int uart_msp_init(USART_Type *USARTx)
{     
    switch((uint32_t)USARTx)
    {
#if defined(BSP_USING_UART1)
        case USART1_BASE:
            usart1_msp_init();
            RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_USART1,ENABLE);          
            break;
#endif
        
#if defined(BSP_USING_UART2)
        case USART2_BASE:
            usart2_msp_init();
            RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_USART2,ENABLE);
            break;
#endif
        
#if defined(BSP_USING_UART3)
        case USART3_BASE:
            usart3_msp_init();
            RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_USART3,ENABLE);
            break; 
#endif
        
#if defined(BSP_USING_UART4)        
        case UART4_BASE:
            uart4_msp_init();
            RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_UART4,ENABLE);
            break;
#endif
        
#if defined(BSP_USING_UART5)        
        case UART5_BASE:
            uart5_msp_init();
            RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_UART5,ENABLE);
            break;  
#endif        
        
        default:
            return RT_ERROR;
    }
    
    return RT_EOK;
}

int uart_hw_init(USART_Type* USARTx)
{    
    USART_InitType USART_InitStruct;
    
    /* UART IO & clock config*/
    uart_msp_init(USARTx);    
    
    /* UART init struct config */
    USART_StructInit(&USART_InitStruct);
    switch((uint32_t)USARTx)
    {
        case USART1_BASE:
            USART_InitStruct.USART_BaudRate = 115200;
            break;
        
        case USART2_BASE:
            USART_InitStruct.USART_BaudRate = 115200;
            break;
        
        case USART3_BASE:
            USART_InitStruct.USART_BaudRate = 115200;
            break;
        
        case UART4_BASE:
            USART_InitStruct.USART_BaudRate = 115200;
            break;
        
        case UART5_BASE:
            USART_InitStruct.USART_BaudRate = 115200;
            break;
        
        default:
            return RT_ERROR;
    }
    
    /* UART init & enable*/
    USART_Init(USARTx,&USART_InitStruct);
    USART_Cmd(USARTx,ENABLE);
    
    return RT_EOK;
}
